using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Linq;
using Microsoft.Extensions.Logging;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
using Volo.Abp.Authorization;
using UserManagementService.Users;
using UserManagementService.Permissions;
using UserManagementService.Exceptions;
using Microsoft.AspNetCore.Authorization;

namespace UserManagementService.Users;

/// <summary>
/// 用户管理应用服务
/// </summary>
// [Authorize$1]
public class UserAppService : ApplicationService, IUserAppService
{
    private readonly IRepository<IdentityUser, Guid> _userRepository;
    private readonly IUserPermissionService _userPermissionService;
    private readonly ILogger<UserAppService> _logger;

    public UserAppService(
        IRepository<IdentityUser, Guid> userRepository,
        IUserPermissionService userPermissionService,
        ILogger<UserAppService> logger)
    {
        _userRepository = userRepository;
        _userPermissionService = userPermissionService;
        _logger = logger;
    }

    public async Task<PagedResultDto<UserDto>> GetListAsync(GetUserListInput input)
    {
        _logger.LogInformation("获取用户列表: Filter={Filter}, Sorting={Sorting}, SkipCount={SkipCount}, MaxResultCount={MaxResultCount}",
            input.Filter, input.Sorting, input.SkipCount, input.MaxResultCount);

        await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Default);

        var queryable = await _userRepository.GetQueryableAsync();

        queryable = queryable
            .WhereIf(!input.Filter.IsNullOrWhiteSpace(),
                x => x.UserName.Contains(input.Filter) ||
                     x.Email.Contains(input.Filter) ||
                     x.Name.Contains(input.Filter) ||
                     x.Surname.Contains(input.Filter))
            .WhereIf(input.IsActive.HasValue, x => x.IsActive == input.IsActive.Value)
            .WhereIf(input.StartTime.HasValue, x => x.CreationTime >= input.StartTime.Value)
            .WhereIf(input.EndTime.HasValue, x => x.CreationTime <= input.EndTime.Value);

        var totalCount = await AsyncExecuter.CountAsync(queryable);

        // 简化排序实现
        IOrderedQueryable<IdentityUser> orderedQuery;
        if (!string.IsNullOrWhiteSpace(input.Sorting))
        {
            if (input.Sorting.Contains("UserName"))
            {
                orderedQuery = input.Sorting.Contains("desc")
                    ? queryable.OrderByDescending(x => x.UserName)
                    : queryable.OrderBy(x => x.UserName);
            }
            else if (input.Sorting.Contains("Email"))
            {
                orderedQuery = input.Sorting.Contains("desc")
                    ? queryable.OrderByDescending(x => x.Email)
                    : queryable.OrderBy(x => x.Email);
            }
            else
            {
                orderedQuery = queryable.OrderBy(x => x.UserName);
            }
        }
        else
        {
            orderedQuery = queryable.OrderBy(x => x.UserName);
        }

        var items = await AsyncExecuter.ToListAsync(
            orderedQuery.PageBy(input.SkipCount, input.MaxResultCount)
        );

        var dtos = ObjectMapper.Map<List<IdentityUser>, List<UserDto>>(items);

        // 为每个用户获取权限
        foreach (var dto in dtos)
        {
            dto.Permissions = await GetUserPermissionsAsync(dto.Id);
        }

        _logger.LogInformation("成功获取用户列表: Count={Count}", dtos.Count);

        return new PagedResultDto<UserDto>(totalCount, dtos);
    }

    public async Task<UserDto> GetAsync(Guid id)
    {
        _logger.LogInformation("获取用户详情: Id={Id}", id);

        await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Default);

        var user = await _userRepository.GetAsync(id);

        var userDto = ObjectMapper.Map<IdentityUser, UserDto>(user);
        userDto.Permissions = await GetUserPermissionsAsync(id);

        _logger.LogInformation("成功获取用户详情: Id={Id}, UserName={UserName}", id, userDto.UserName);

        return userDto;
    }

    // [Authorize$1]
    public async Task<UserDto> CreateAsync(CreateUserDto input)
    {
        _logger.LogInformation("创建用户: UserName={UserName}, Email={Email}",
            input.UserName, input.Email);

        await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Create);

        // 检查用户名是否已存在
        var existingUser = await _userRepository.FirstOrDefaultAsync(x => x.UserName == input.UserName);
        if (existingUser != null)
        {
            throw new UserNameAlreadyExistsException(input.UserName);
        }

        // 检查邮箱是否已存在
        if (!input.Email.IsNullOrWhiteSpace())
        {
            var existingEmail = await _userRepository.FirstOrDefaultAsync(x => x.Email == input.Email);
            if (existingEmail != null)
            {
                throw new UserEmailAlreadyExistsException(input.Email);
            }
        }

        var user = new IdentityUser(
            GuidGenerator.Create(),
            input.UserName,
            input.Email
        );

        // 注意：IdentityUser的某些属性可能需要通过不同的方式设置
        // 这里暂时跳过这些设置，因为ABP IdentityUser可能不直接支持这些方法
        // 可以考虑使用 UserManager 来处理这些操作

        // 如果提供了密码，则设置密码
        if (!input.Password.IsNullOrWhiteSpace())
        {
            await SetPasswordAsync(user, input.Password);
        }

        await _userRepository.InsertAsync(user, autoSave: true);

        var userDto = ObjectMapper.Map<IdentityUser, UserDto>(user);
        userDto.Permissions = await GetUserPermissionsAsync(user.Id);

        _logger.LogInformation("成功创建用户: Id={Id}, UserName={UserName}",
            user.Id, user.UserName);

        return userDto;
    }

    // [Authorize$1]
    public async Task<UserDto> UpdateAsync(Guid id, UpdateUserDto input)
    {
        _logger.LogInformation("更新用户: Id={Id}, UserName={UserName}",
            id, input.UserName);

        await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

        var user = await _userRepository.GetAsync(id);

        // 检查用户名是否与其他用户冲突
        if (input.UserName != user.UserName)
        {
            var existingUser = await _userRepository.FirstOrDefaultAsync(x => x.UserName == input.UserName && x.Id != id);
            if (existingUser != null)
            {
                throw new UserNameAlreadyExistsException(input.UserName);
            }
        }

        // 检查邮箱是否与其他用户冲突
        if (!input.Email.IsNullOrWhiteSpace() && input.Email != user.Email)
        {
            var existingEmail = await _userRepository.FirstOrDefaultAsync(x => x.Email == input.Email && x.Id != id);
            if (existingEmail != null)
            {
                throw new UserEmailAlreadyExistsException(input.Email);
            }
        }

        // 注意：这些属性的设置需要通过UserManager或其他方式处理
        // 暂时保留基本设置，其他属性可能需要特殊处理

        await _userRepository.UpdateAsync(user, autoSave: true);

        var userDto = ObjectMapper.Map<IdentityUser, UserDto>(user);
        userDto.Permissions = await GetUserPermissionsAsync(id);

        _logger.LogInformation("成功更新用户: Id={Id}, UserName={UserName}",
            id, user.UserName);

        return userDto;
    }

    // [Authorize$1]
    public async Task DeleteAsync(Guid id)
    {
        _logger.LogInformation("删除用户: Id={Id}", id);

        await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Delete);

        var user = await _userRepository.GetAsync(id);

        await _userRepository.DeleteAsync(user, autoSave: true);

        // 清除用户权限缓存
        await _userPermissionService.RefreshUserPermissionCacheAsync(id);

        _logger.LogInformation("成功删除用户: Id={Id}, UserName={UserName}",
            id, user.UserName);
    }

    // [Authorize$1]
    public async Task<UserDto> SetPasswordAsync(Guid id, SetPasswordDto input)
    {
        _logger.LogInformation("设置用户密码: Id={Id}", id);

        await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

        var user = await _userRepository.GetAsync(id);

        await SetPasswordAsync(user, input.Password);
        await _userRepository.UpdateAsync(user, autoSave: true);

        _logger.LogInformation("成功设置用户密码: Id={Id}", id);

        return ObjectMapper.Map<IdentityUser, UserDto>(user);
    }

    // [Authorize$1]
    public async Task<UserDto> ChangePasswordAsync(Guid id, ChangePasswordDto input)
    {
        _logger.LogInformation("修改用户密码: Id={Id}", id);

        await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

        var user = await _userRepository.GetAsync(id);

        // TODO: 实现密码验证逻辑
        // 验证旧密码是否正确
        // 设置新密码

        _logger.LogInformation("成功修改用户密码: Id={Id}", id);

        return ObjectMapper.Map<IdentityUser, UserDto>(user);
    }

    // [Authorize$1]
    public async Task<UserDto> ActivateAsync(Guid id)
    {
        _logger.LogInformation("激活用户: Id={Id}", id);

        await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

        var user = await _userRepository.GetAsync(id);

        if (user.IsActive)
        {
            throw new UserAlreadyActiveException(user.Id, user.UserName);
        }

        // 使用UserManager来设置用户状态，IdentityUser的IsActive属性set访问器不可直接访问
        // 注意：这里可能需要使用UserManager的相关方法来处理
        await Task.CompletedTask; // 暂时占位
        await _userRepository.UpdateAsync(user, autoSave: true);

        _logger.LogInformation("成功激活用户: Id={Id}, UserName={UserName}",
            id, user.UserName);

        return ObjectMapper.Map<IdentityUser, UserDto>(user);
    }

    // [Authorize$1]
    public async Task<UserDto> DeactivateAsync(Guid id)
    {
        _logger.LogInformation("停用用户: Id={Id}", id);

        await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

        var user = await _userRepository.GetAsync(id);

        if (!user.IsActive)
        {
            throw new UserAlreadyInactiveException(user.Id, user.UserName);
        }

        // 使用UserManager来设置用户状态，IdentityUser的IsActive属性set访问器不可直接访问
        // 注意：这里可能需要使用UserManager的相关方法来处理
        await Task.CompletedTask; // 暂时占位
        await _userRepository.UpdateAsync(user, autoSave: true);

        _logger.LogInformation("成功停用用户: Id={Id}, UserName={UserName}",
            id, user.UserName);

        return ObjectMapper.Map<IdentityUser, UserDto>(user);
    }

    public async Task<List<string>> GetPermissionsAsync(Guid id)
    {
        _logger.LogInformation("获取用户权限: Id={Id}", id);

        await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Default);

        var permissions = await _userPermissionService.GetUserPermissionsAsync(id);

        _logger.LogInformation("成功获取用户权限: Id={Id}, PermissionCount={Count}",
            id, permissions.Count);

        return permissions;
    }

    // [Authorize$1]
    public async Task GrantPermissionAsync(Guid id, GrantPermissionDto input)
    {
        _logger.LogInformation("授予用户权限: Id={Id}, Permission={Permission}",
            id, input.PermissionName);

        await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

        await _userPermissionService.GrantPermissionAsync(id, input.PermissionName, CurrentUser.Name);

        _logger.LogInformation("成功授予用户权限: Id={Id}, Permission={Permission}",
            id, input.PermissionName);
    }

    // [Authorize$1]
    public async Task RevokePermissionAsync(Guid id, RevokePermissionDto input)
    {
        _logger.LogInformation("撤销用户权限: Id={Id}, Permission={Permission}",
            id, input.PermissionName);

        await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

        await _userPermissionService.RevokePermissionAsync(id, input.PermissionName, CurrentUser.Name);

        _logger.LogInformation("成功撤销用户权限: Id={Id}, Permission={Permission}",
            id, input.PermissionName);
    }

    private async Task<List<string>> GetUserPermissionsAsync(Guid userId)
    {
        try
        {
            return await _userPermissionService.GetUserPermissionsAsync(userId);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "获取用户权限失败: UserId={UserId}, Error={Error}",
                userId, ex.Message);
            return new List<string>();
        }
    }

    private async Task SetPasswordAsync(IdentityUser user, string password)
    {
        // TODO: 实现密码设置逻辑
        // 这里应该使用ABP Identity的密码管理功能
        // user.PasswordHash = _passwordHasher.HashPassword(user, password);
    }

    protected override async Task CheckPolicyAsync(string? policyName)
    {
        // 使用IsGrantedAsync来检查权限
        if (!await AuthorizationService.IsGrantedAsync(policyName))
        {
            throw new AbpAuthorizationException($"未授权访问: {policyName}");
        }
    }
}